import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class IPPacketFragmentation1 {
    private static final int FRAGMENT_SIZE = 10;
    //Packet类来表示IP数据包
    public static class Packet {
        private int id;
        private int offset;
        private boolean moreFragments;
        private byte[] data;

        public Packet(int id, int offset, boolean moreFragments, byte[] data) {
            this.id = id;
            this.offset = offset;
            this.moreFragments = moreFragments;
            this.data = data;
        }
    }
    //fragmentPacket()方法中，我们根据给定的分片大小和数据包的总大小计算出分片的数量，
    // 并使用循环将原始数据包分成多个分片。
    // 每个分片都包含原始数据包的ID、偏移量（offset）、更多分片标志（moreFragments）以及对应的数据。
    public static List<Packet> fragmentPacket(Packet packet) {
        List<Packet> fragments = new ArrayList<>();
        int totalFragments = (packet.data.length / FRAGMENT_SIZE) + 1;
        int offset = 0;

        for (int i = 0; i < totalFragments; i++) {
            int dataSize = Math.min(FRAGMENT_SIZE, packet.data.length - offset);
            byte[] fragmentData = new byte[dataSize];
            System.arraycopy(packet.data, offset, fragmentData, 0, dataSize);

            Packet fragment = new Packet(packet.id, offset, (offset + dataSize) < packet.data.length, fragmentData);
            fragments.add(fragment);

            offset += dataSize;
        }

        return fragments;
    }
    //reassemblePacket()方法接收一个分片列表作为参数，在循环中将所有分片的数据拼接起来，生成重组后的数据包。
    public static Packet reassemblePacket(List<Packet> fragments) {
        int totalDataSize = fragments.stream().mapToInt(fragment -> fragment.data.length).sum();
        byte[] assembledData = new byte[totalDataSize];
        int offset = 0;

        for (Packet fragment : fragments) {
            System.arraycopy(fragment.data, 0, assembledData, offset, fragment.data.length);
            offset += fragment.data.length;
        }

        return new Packet(fragments.get(0).id, 0, fragments.get(fragments.size() - 1).moreFragments, assembledData);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入需要分片的数据包");
        String in = scanner.nextLine();
        Packet originalPacket = new Packet(1234, 0, false,in.getBytes());

        System.out.println("原始数据包:");
        System.out.println("ID: " + originalPacket.id);
        System.out.println("偏移量: " + originalPacket.offset);
        System.out.println("更多分片: " + originalPacket.moreFragments);
        System.out.println("数据: " + new String(originalPacket.data) + "\n");

        List<Packet> fragments = fragmentPacket(originalPacket);
        System.out.println("分片如下：");
        System.out.println();
        for (int i = 0; i < fragments.size(); i++) {
            Packet fragment = fragments.get(i);
            System.out.println("片段 " + (i + 1) + "/" + fragments.size() + ":");
            System.out.println("ID: " + fragment.id);
            System.out.println("偏移量: " + fragment.offset);
            System.out.println("更多分片: " + fragment.moreFragments);
            System.out.println("数据: " + new String(fragment.data) + "\n");
        }

        Packet reassembledPacket = reassemblePacket(fragments);
        System.out.println();
        System.out.println("重组如下：");
        System.out.println();
        System.out.println("原始数据包:");
        System.out.println("ID: " + reassembledPacket.id);
        System.out.println("偏移量: " + reassembledPacket.offset);
        System.out.println("更多分片: " + reassembledPacket.moreFragments);
        System.out.println("数据: " + new String(reassembledPacket.data));
    }
}

